<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <script src="https://cdn.tailwindcss.com"></script>
  <title>戏剧四大行当拼图游戏</title>
  <style>
    :root { --piece-size: 30vw; --drop-padding: 0.5rem; }
    @media (min-width: 640px) { :root { --piece-size: 200px; } }
    body, #game-container { touch-action: none; }

    .draggable {
      width: var(--piece-size);
      height: var(--piece-size);
      object-fit: contain;
      cursor: grab;
      touch-action: none;
      user-select: none;
      position: relative;
      flex: 0 0 auto;
    }
    .draggable.placeholder {
      visibility: hidden;
      flex: 0 0 var(--piece-size);
    }
    .dragging {
      cursor: grabbing;
      z-index: 1000;
      transition: transform 0.1s ease;
      transform-origin: top left;
      box-shadow: 0 8px 20px rgba(0,0,0,0.2);
      transform: scale(1.05);
    }

    .dropzone {
      border: 2px dashed #ccc;
      width: var(--piece-size);
      height: var(--piece-size);
      display: flex;
      align-items: center;
      justify-content: center;
      padding: var(--drop-padding);
      font-size: calc(var(--piece-size) / 5);
      color: #999;
      position: relative;
      overflow: hidden;
      flex: 0 0 auto;
    }
    .dropzone.correct { border-color: green; }
    .dropzone img {
      position: absolute;
      top: 0; left: 0;
      width: 100%; height: 100%;
      object-fit: contain;
      z-index: 2;
      touch-action: none;
    }
  </style>
</head>
<body class="bg-gray-100 p-4">
  <h1 class="text-2xl sm:text-3xl font-bold text-center mb-4">戏剧四大行当拼图游戏</h1>
  <div id="main-menu" class="flex flex-col items-center gap-2 mb-4">
    <button id="basic-game-button" class="bg-blue-500 text-white font-bold py-2 px-4 rounded">基础游戏</button>
    <button id="advanced-game-button" class="bg-green-500 text-white font-bold py-2 px-4 rounded">进阶游戏</button>
  </div>
  <div id="role-menu" class="hidden grid grid-cols-2 sm:grid-cols-4 gap-2 justify-items-center mb-4 w-full max-w-md mx-auto">
    <button data-role="sheng" class="role-button bg-yellow-500 text-white py-2 px-4 rounded text-sm">生角游戏</button>
    <button data-role="dan"   class="role-button bg-purple-500 text-white py-2 px-4 rounded text-sm">旦角游戏</button>
    <button data-role="jing"  class="role-button bg-orange-500 text-white py-2 px-4 rounded text-sm">净角游戏</button>
    <button data-role="chou"  class="role-button bg-pink-500 text-white py-2 px-4 rounded text-sm">丑角游戏</button>
  </div>
  <div id="game-container" class="hidden flex flex-col items-center gap-4">
    <div id="draggable-container" class="flex flex-wrap justify-center gap-2"></div>
    <div id="dropzone-container" class="flex flex-wrap justify-center gap-2"></div>
  </div>
  <div class="flex flex-col items-center gap-2 mt-4">
    <button id="check-answer-button" class="hidden bg-green-500 text-white py-2 px-4 rounded">核对答案</button>
    <div id="result-message" class="hidden text-center font-bold mt-2"></div>
    <button id="back-button" class="hidden bg-red-500 text-white py-2 px-4 rounded">返回主界面</button>
  </div>

  <script>
        const basicImages = [
      { id:'sheng', src:'生.jpg', sub:'生' },
      { id:'dan',   src:'旦.jpg', sub:'旦' },
      { id:'jing',  src:'净.jpg', sub:'净' },
      { id:'chou',  src:'丑.png', sub:'丑' }
    ];
    const advancedImages = {
      sheng: [{id:'xiaosheng',src:'小生.jpg',sub:'小生'}, {id:'laosheng',src:'老生.jpg',sub:'老生'}, {id:'wusheng',src:'武生.jpg',sub:'武生'}],
      dan:   [{id:'qingyi',src:'青衣.jpg',sub:'青衣'}, {id:'huadan',src:'花旦.jpg',sub:'花旦'}, {id:'laodan',src:'老旦.jpg',sub:'老旦'}, {id:'wudan',src:'武旦.jpg',sub:'武旦'}],
      jing:  [{id:'jiazi',src:'架子.jpg',sub:'架子'}, {id:'tongchui',src:'铜锤.jpg',sub:'铜锤'}, {id:'wujing',src:'武净.jpg',sub:'武净'}],
      chou:  [{id:'wenchou',src:'文丑.jpg',sub:'文丑'}, {id:'wuchou',src:'武丑.jpg',sub:'武丑'}]
    };

    const $ = id => document.getElementById(id);
    function show(el){ el.classList.remove('hidden'); }
    function hide(el){ el.classList.add('hidden'); }

    $('basic-game-button').onclick = () => startGame(basicImages);
    $('advanced-game-button').onclick = () => { hide($('main-menu')); show($('role-menu')); show($('back-button')); };
    document.querySelectorAll('.role-button').forEach(b => b.onclick = () => startGame(advancedImages[b.dataset.role]));
    $('back-button').onclick = () => location.reload();
    $('check-answer-button').onclick = checkAnswer;

    function shuffle(a){
      for (let i = a.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [a[i], a[j]] = [a[j], a[i]];
      }
      return a;
    }

    function startGame(imgs) {
      hide($('main-menu'));
      hide($('role-menu'));
      show($('game-container'));
      show($('check-answer-button'));
      show($('back-button'));
      hide($('result-message'));

      const dc = $('draggable-container');
      const dzc = $('dropzone-container');
      dc.innerHTML = '';
      dzc.innerHTML = '';

      shuffle(imgs.slice()).forEach(it => {
        const img = new Image();
        img.src = it.src;
        img.id = it.id;
        img.dataset.sub = it.sub;
        img.className = 'draggable';
        img.draggable = false;
        dc.appendChild(img);
      });

      imgs.forEach(it => {
        const dz = document.createElement('div');
        dz.className = 'dropzone';
        dz.dataset.sub = it.sub;
        const span = document.createElement('span');
        span.className = 'placeholder';
        span.textContent = it.sub;
        dz.appendChild(span);
        dzc.appendChild(dz);
      });

      initDrag();
    }

    function initDrag() {
      let cur = null;
      let placeholder = null;

      document.querySelectorAll('.draggable').forEach(el => {
        el.addEventListener('pointerdown', e => {
          if (e.pointerType === 'touch' || e.pointerType === 'mouse') {
            e.preventDefault();
            cur = el;
            const r = cur.getBoundingClientRect();
            cur.dataset.offsetX = e.clientX - r.left;
            cur.dataset.offsetY = e.clientY - r.top;

            // placeholder
            placeholder = document.createElement('div');
            placeholder.className = 'draggable placeholder';
            el.parentNode.insertBefore(placeholder, el);

            cur.setPointerCapture(e.pointerId);
            cur.classList.add('dragging');
            document.body.appendChild(cur);
            cur.style.position = 'absolute';
            cur.style.left = '0';
            cur.style.top = '0';
            cur.style.transform = `translate(${r.left}px, ${r.top}px)`;
          }
        }, { passive: false });
      });

      document.addEventListener('pointermove', e => {
        if (!cur) return;
        e.preventDefault();
        const x = e.clientX - parseFloat(cur.dataset.offsetX);
        const y = e.clientY - parseFloat(cur.dataset.offsetY);
        cur.style.transform = `translate(${x}px, ${y}px)`;
      }, { passive: false });

      document.addEventListener('pointerup', e => {
        if (!cur) return;
        cur.releasePointerCapture(e.pointerId);
        cur.classList.remove('dragging');

        const r = cur.getBoundingClientRect();
        const cx = r.left + r.width / 2;
        const cy = r.top + r.height / 2;
        let placed = false;

        document.querySelectorAll('.dropzone').forEach(dz => {
          const d = dz.getBoundingClientRect();
          if (cx >= d.left && cx <= d.right && cy >= d.top && cy <= d.bottom) {
            const existing = dz.querySelector('img');
            if (existing) $('draggable-container').appendChild(existing);
            dz.appendChild(cur);
            dz.querySelector('.placeholder').style.display = 'none';
            placed = true;
          }
        });

        if (!placed) {
          $('draggable-container').appendChild(cur);
        }

        // cleanup
        placeholder && placeholder.remove();
        cur.style.position = 'static';
        cur.style.transform = '';
        cur = null;
        placeholder = null;
      }, { passive: false });
    }

    function checkAnswer() {
      let ok = true;
      document.querySelectorAll('.dropzone').forEach(dz => {
        const img = dz.querySelector('img');
        if (!img || img.dataset.sub !== dz.dataset.sub) {
          ok = false;
          dz.classList.remove('correct');
        } else {
          dz.classList.add('correct');
        }
      });
      show($('result-message'));
      $('result-message').textContent = ok ? '恭喜你，答案全部正确！' : '很遗憾，答案有误，请继续努力！';
      $('result-message').className = ok ? 'text-green-600 font-bold mt-2' : 'text-red-600 font-bold mt-2';
    }
  </script>
</body>
</html>
